package dataImport.model;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import dataImport.action.NpcReader;
import dataImport.action.ObjectReader;
import dataImport.action.PlaceReader;
import dataImport.action.abstracts.AbstractEntityReader;
import dataImport.action.manager.EntityReaderManager;
import dataImport.model.abstracts.AbstractEntity;
import dataImport.model.abstracts.AbstractInteractableEntity;


public class Text extends AbstractEntity {

	private static final String REPLACE_SEPARATOR = ",";
	private static final String DELIMITER = "@";
	private static final long serialVersionUID = -1574885053294582601L;

	public Text(final String id) {
		super(id);
	}

	@Override
	public String toString() {
		return this.getId();
	}

	public Text(final String id, final EntityReaderManager entityReaderManager) {
		super(fixText(id, entityReaderManager, TextSubstititionType.TO_STRING));
	}

	public Text(final String id, final EntityReaderManager entityReaderManager, final String replacement) {
		super(fixText(id, entityReaderManager, replacement, TextSubstititionType.NAME));
	}
	
	public final static boolean hasReplace(final String text) {
		return text.contains(DELIMITER); 
	}
	
	private final static String fixText(final String text, final EntityReaderManager entityReaderManager, final String replacement, final TextSubstititionType textSubstititionType) {		
		final String[] replacements = replacement.replaceAll(" ", "").split(REPLACE_SEPARATOR);
		
		String newText = "";
		String temp = text;
		
		int lastDelimiterPosition = 0;
		int currentDelimiterPosition = 0;
		
		for (int i = 0; i < replacements.length; i++) {
			currentDelimiterPosition = temp.indexOf(DELIMITER);
			
			if (currentDelimiterPosition >= 0) {
				newText += temp.substring(0, currentDelimiterPosition);
			}
			newText += DELIMITER + replacements[i] + DELIMITER;
			
			currentDelimiterPosition++;
			if (currentDelimiterPosition < temp.length()) {
				temp = temp.substring(currentDelimiterPosition);				
			}
			
			lastDelimiterPosition += currentDelimiterPosition;
		}
		
		if (lastDelimiterPosition < text.length()) {
			newText += text.substring(lastDelimiterPosition);
		}

		return fixText(newText, entityReaderManager, textSubstititionType);
	}
	
	private final static String fixText(final String text, final EntityReaderManager entityReaderManager, final TextSubstititionType textSubstititionType) {
		String newText = text;

		final PlaceReader placeReader = entityReaderManager.getPlaceReader();
		newText = fixText(newText, PlaceReader.ENTITY_NAME, placeReader, textSubstititionType);

		final ObjectReader objectReader = entityReaderManager.getObjectReader();
		newText = fixText(newText, ObjectReader.ENTITY_NAME, objectReader, textSubstititionType);

		final NpcReader npcReader = entityReaderManager.getNpcReader();
		newText = fixText(newText, NpcReader.ENTITY_NAME, npcReader, textSubstititionType);

		return newText;
	}
	
	private static final String fixText(final String text, final String entityName, final AbstractEntityReader abstractEntityReader, final TextSubstititionType textSubstititionType) {
		final String PREFIX = DELIMITER + entityName + ":";
		final String SUFFIX = DELIMITER;

		String newText = text;
		Pattern pattern = null;
		Matcher matcher = null;

		pattern = Pattern.compile(PREFIX + "\\w*" + SUFFIX);
		matcher = pattern.matcher(newText);

		while (matcher.find()) {
			final String id = matcher.group().replaceFirst(PREFIX, "").replaceFirst(SUFFIX, "");
			newText = replace(newText, matcher.group(), abstractEntityReader.getEntityWithId(id), textSubstititionType);
		}

		return newText;
	}

	private static final String replace(final String text, final String regex, final AbstractEntity abstractEntity, final TextSubstititionType textSubstititionType) {
		switch (textSubstititionType) {
			case NAME:
				return replaceByName(text, regex, (AbstractInteractableEntity) abstractEntity);
			case TO_STRING:
				return replaceByToString(text, regex, abstractEntity);
			default:
				return null;
		}
	}

	private static final String replaceByToString(final String text, final String regex, final AbstractEntity abstractEntity) {
		return text.replaceAll(regex, abstractEntity.toString());
	}

	private static final String replaceByName(final String text, final String regex, final AbstractInteractableEntity abstractInteractableEntity) {
		return text.replaceAll(regex, abstractInteractableEntity.getName());
	}

	public enum TextSubstititionType {
		TO_STRING, NAME
	}
}
